import * as fs from 'fs';
import * as path from 'path';
import { spawn } from 'child_process';

export default async function (context) {
  const { electronPlatformName, appOutDir } = context;

  // Only notarize on macOS platform
  if (electronPlatformName !== 'darwin') {
    console.log('Skipping notarization: Not macOS platform');
    return;
  }

  // Check if notarization is explicitly disabled
  if (process.env.NOTARIZE === 'false' || process.env.SKIP_NOTARIZATION === 'true') {
    console.log('⚠️  Notarization explicitly disabled, skipping...');
    return;
  }

  // Check if code signing was skipped
  if (process.env.CSC_IDENTITY_AUTO_DISCOVERY === 'false') {
    console.log('⚠️  Code signing disabled, skipping notarization...');
    return;
  }

  // Check required environment variables
  if (!process.env.APPLE_ID || !process.env.APPLE_APP_SPECIFIC_PASSWORD || !process.env.APPLE_TEAM_ID) {
    console.warn('⚠️  Notarization credentials not found, skipping notarization');
    console.log('Please set the following environment variables:');
    console.log('- APPLE_ID: Apple Developer account');
    console.log('- APPLE_APP_SPECIFIC_PASSWORD: App-specific password');
    console.log('- APPLE_TEAM_ID: Certificate provider (Team ID)');
    return;
  }

  console.log('Starting macOS app notarization...');

  // Get app path and info
  const appName = context.packager.appInfo.productFilename;
  const appPath = `${appOutDir}/${appName}.app`;

  console.log(`App path: ${appPath}`);
  console.log(`Bundle ID: com.302ai.302aistudio`);
  console.log(`Certificate provider: ${process.env.APPLE_TEAM_ID}`);

  // Wait for app bundle to be fully available
  console.log('Waiting for app bundle to be fully available...');
  await new Promise(resolve => setTimeout(resolve, 5000));

  // Verify app bundle exists
  if (!fs.existsSync(appPath)) {
    throw new Error(`App bundle not found at: ${appPath}`);
  }

  // Use direct notarytool command instead of @electron/notarize
  try {
    console.log('Preparing app bundle for notarization...');
    
    // Create a zip file of the app bundle for notarization
    const appDir = path.dirname(appPath);
    const appBasename = path.basename(appPath);
    const zipPath = `${appPath}.zip`;
    
    console.log(`Creating zip file: ${zipPath}`);
    
    // Create zip file using ditto command (preserves metadata and symlinks)
    const zipResult = await runCommand('ditto', [
      '-c', '-k', '--sequesterRsrc', '--keepParent',
      appBasename, `${appBasename}.zip`
    ], appDir);
    
    if (!zipResult.success) {
      throw new Error(`Failed to create zip file: ${zipResult.error}`);
    }
    
    console.log('✅ Zip file created successfully');
    console.log('Uploading app for notarization using notarytool, this may take several minutes...');

    // Step 1: Submit zip file for notarization
    const submitResult = await runCommand('xcrun', [
      'notarytool', 'submit', zipPath,
      '--apple-id', process.env.APPLE_ID,
      '--password', process.env.APPLE_APP_SPECIFIC_PASSWORD,
      '--team-id', process.env.APPLE_TEAM_ID,
      '--wait'
    ]);

    if (submitResult.success) {
      console.log('✅ App notarization successful!');
      console.log('Notarization output:', submitResult.output);
      
      // Step 2: Staple the notarization ticket to the app
      console.log('Stapling notarization ticket to app...');
      const stapleResult = await runCommand('xcrun', [
        'stapler', 'staple', appPath
      ]);
      
      if (stapleResult.success) {
        console.log('✅ Notarization ticket stapled successfully!');
      } else {
        console.warn('⚠️  Failed to staple notarization ticket:', stapleResult.error);
        console.warn('App is notarized but ticket is not stapled');
      }
      
      // Clean up zip file
      try {
        fs.unlinkSync(zipPath);
        console.log('Cleaned up temporary zip file');
      } catch (cleanupError) {
        console.warn('Warning: Could not clean up zip file:', cleanupError.message);
      }
      
    } else {
      throw new Error(`Notarization failed: ${submitResult.error}`);
    }

  } catch (error) {
    console.error('❌ App notarization failed:', error.message);

    // Provide error handling suggestions
    if (error.message.includes('Invalid credentials') || error.message.includes('authentication')) {
      console.error('Please check if Apple ID and app-specific password are correct');
    } else if (error.message.includes('Bundle ID') || error.message.includes('bundle')) {
      console.error('Please check if Bundle ID matches your Apple Developer account');
    } else if (error.message.includes('network') || error.message.includes('connection')) {
      console.error('Network connection issue, please check your internet connection');
    }

    // In CI environment, notarization failure should cause build to fail
    if (process.env.CI) {
      throw error;
    } else {
      console.warn('Local build continues, but app is not notarized');
    }
  }
}

// Helper function to run shell commands
function runCommand(command, args, cwd = null) {
  return new Promise((resolve) => {
    const options = {
      stdio: ['pipe', 'pipe', 'pipe']
    };
    
    if (cwd) {
      options.cwd = cwd;
    }
    
    const proc = spawn(command, args, options);

    let stdout = '';
    let stderr = '';

    proc.stdout.on('data', (data) => {
      const output = data.toString();
      stdout += output;
      console.log(output.trim());
    });

    proc.stderr.on('data', (data) => {
      const output = data.toString();
      stderr += output;
      console.error(output.trim());
    });

    proc.on('close', (code) => {
      if (code === 0) {
        resolve({ success: true, output: stdout });
      } else {
        resolve({ success: false, error: stderr || stdout });
      }
    });

    proc.on('error', (error) => {
      resolve({ success: false, error: error.message });
    });
  });
}

